package com.ilikesoup.instant.classifier;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * @ClassName ActionBuilder
 * @Description: 动作链构建器
 * @Author gaoxiang
 * @Date 2020/8/7 16:25
 * @Version V1.0
 *
 * 构建动作链，则需要 new ActionBuilder<T>().action(xxx).action(xxx).build();
 **/
public class ActionBuilder<T> {

    private List<Action<T, ?>> actions = new ArrayList<>();

    public ActionBuilder<T> action(Action<T, ?> action) {
        actions.add(action);
        return this;
    }

    public ActionBuilder<T> action(String name, Action<T, ?> action) {
        actions.add(new Action.NamedAction<>(name, action));
        return this;
    }

    public <E> ActionBuilder<T> action(Consumer<T> consumer, E defVal) {
        actions.add(new Action.ConsumeAction<>(consumer, defVal));
        return this;
    }

    public <E> ActionBuilder<T> action(String name, Consumer<T> consumer, E defVal) {
        actions.add(new Action.NamedAction<>(name, new Action.ConsumeAction<>(consumer, defVal)));
        return this;
    }

    public <E> ActionBuilder<T> action(BiConsumer<T, E> consumer, E parameter) {
        actions.add(new Action.ExConsumeAction<>(consumer, parameter));
        return this;
    }

    public <E> ActionBuilder<T> action(String name, BiConsumer<T, E> consumer, E parameter) {
        actions.add(new Action.NamedAction<>(name, new Action.ExConsumeAction<>(consumer, parameter)));
        return this;
    }

    public <E> ActionBuilder<T> action(Function<T, E> converter) {
        actions.add(new Action.ConvertAction<>(converter));
        return this;
    }

    public <E> ActionBuilder<T> action(String name, Function<T, E> converter) {
        actions.add(new Action.NamedAction<>(name, new Action.ConvertAction<>(converter)));
        return this;
    }

    public <E, U> ActionBuilder<T> action(BiFunction<T, U, E> converter, U parameter) {
        actions.add(new Action.ExConvertAction<>(converter, parameter));
        return this;
    }

    public <E, U> ActionBuilder<T> action(String name, BiFunction<T, U, E> converter, U parameter) {
        actions.add(new Action.NamedAction<>(name, new Action.ExConvertAction<>(converter, parameter)));
        return this;
    }

    public Action<T, List<Object>> build() {
        return new Action.ActionChain<T>(actions);
    }

    public Action<T, Map<String, Object>> buildNamed() {
        return new Action.NamedActionChain<T>(actions);
    }





}
